/*
 * Copyright (c) 2019 Actions Semiconductor Co., Ltd
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file power manager interface
 */
#if defined(CONFIG_SYS_LOG)
#define SYS_LOG_NO_NEWLINE
#ifdef SYS_LOG_DOMAIN
#undef SYS_LOG_DOMAIN
#endif
#define SYS_LOG_DOMAIN "power"
#include <logging/sys_log.h>
#endif

#include <os_common_api.h>
#include <soc.h>
#include <mem_manager.h>
#include <msg_manager.h>
#include <bt_manager.h>
#include <sys_event.h>
#include <sys_monitor.h>
#include <property_manager.h>
#include <power_supply.h>
#include <btservice_api.h>
#include <bt_manager.h>
#include <gpio.h>
#include <board.h>
#include <hotplug_manager.h>
#include <drivers/console/uart_pipe.h>
#include <ui_manager.h>
#include <power_manager.h>

#define DEFAULT_BOOTPOWER_LEVEL	3100000
#define DEFAULT_NOPOWER_LEVEL	    3300000
#define DEFAULT_LOWPOWER_LEVEL	3600000
#define DEFAULT_LOWERPOWER_LEVEL	3500000
#define DEFAULT_FULLPOWER_LEVEL	4000000

#define DEFAULT_REPORT_PERIODS	(300*1000)

//#define UART_TEST_MODE
struct power_manager_info {
	struct device *dev;
	bat_charge_callback_t cb;
	bat_charge_event_t event;
	bat_charge_event_para_t *para;
	int nopower_level;
	int lowpower_level;
	int current_vol;
	int current_cap;
	int slave_vol;
	int slave_cap;
	int battary_changed;
	u32_t charge_full_flag;
	u32_t report_timestamp;
	u8_t low_power_flag;
};

struct power_manager_info *power_manager = NULL;
struct device		*charger_gpio_dev;
//struct k_timer io_ctl_timer;
#if 0
struct thread_timer io_ctl_timer;
#endif
u8_t output_mode=0;
u8_t send_sync_msg=0;
u8_t bat_full_flag=0;

#ifdef UART_TEST_MODE
struct uart_data_format {
    u8_t magic;
    u8_t data_len;
    u8_t cmd_len;
    u8_t cmd_type;
	u8_t data[2];
}__packed;
struct uart_buf_info {
	u32_t _reserved;
    union{
        u8_t data[30];//magic+len+data(cmd_type+cmd_data)
        struct uart_data_format data_info;
    };
};

//static K_FIFO_DEFINE(avail_queue_uart1);

void uart_send_to_apt(     u8_t *p_data)
{
	struct uart_data_format *p_reply = (void *)p_data;
	u16_t writen_len = p_reply->data_len;
	printk("TX:\n");
    print_buffer(p_data, 1, writen_len, 16, 0);
    //SYS_LOG_INF("send msg to apt 11!!\n");
    uart_pipe_send((u8_t *)p_reply, writen_len);
}
void send_tx_msg(void)
{
	struct uart_data_format tx_msg;
	tx_msg.magic=0xAA;	
	tx_msg.cmd_len=3;
	tx_msg.cmd_type=0x02;
	tx_msg.data_len=6;
	tx_msg.data[0]=0x05;
	tx_msg.data[1]=0x06;
	
	uart_send_to_apt((u8_t*)&tx_msg);
}

void set_tx_msg_by_pwm(u8_t* data,u8_t length)
{
	gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN, GPIO_DIR_OUT);
	gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
	k_sleep(5);
	mute_set_ctl_msg(data,length);
}

#endif

void switch_io_func_to_pwm(void)
{
	gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN, GPIO_DIR_OUT);
	gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
	k_sleep(5);
}
void switch_io_func_to_uart_rx(void)
{
	unsigned int mode;
	mode=0x7 | GPIO_CTL_SMIT | GPIO_CTL_PADDRV_LEVEL(3) | GPIO_CTL_PULLUP;
	acts_pinmux_set(BOARD_UART1_RX_PIN,mode);
}
void sync_msg_to_remote_by_pwm(u8_t* data,u8_t length)
{
	SYS_LOG_INF("TX msg!!\n");
	mute_set_ctl_msg(data,length);
}

void link_mute_io_ctl(u8_t mode,u8_t onoff,u8_t rx_flag);
void set_bat_status(u8_t status)
{
	bat_full_flag=status;
}
u8_t get_bat_status(void)
{
	return bat_full_flag;
}
void linein_func_switch(u8_t mode)
{
	if (!charger_gpio_dev)
	{
		return;
	}
	//output
	if(mode)
	{
		gpio_pin_write(charger_gpio_dev,BOARD_LINK_CTL_PIN,0);
		gpio_pin_write(charger_gpio_dev,BOARD_PLAY_CTL_PIN,0);
	}
	else
	{
		gpio_pin_write(charger_gpio_dev,BOARD_LINK_CTL_PIN,1);
		gpio_pin_write(charger_gpio_dev,BOARD_PLAY_CTL_PIN,1);
	}
}

void exmic_mute_int_en_ctl(u8_t onoff)
{
	if (!charger_gpio_dev)
	{
		return;
	}
	if(onoff)
	{
		gpio_pin_enable_callback(charger_gpio_dev, BOARD_EXMIC_MUTE_DEL_PIN);
		//gpio_pin_enable_callback(charger_gpio_dev, BOARD_LINK_MUTE_DEL_PIN);
		
	}
	else
	{		
		gpio_pin_disable_callback(charger_gpio_dev, BOARD_EXMIC_MUTE_DEL_PIN);
		//gpio_pin_enable_callback(charger_gpio_dev, BOARD_LINK_MUTE_DEL_PIN);
	}
}

void bt_boost_en_ctl(u8_t onoff)
{
	if (!charger_gpio_dev)
	{
		return;
	}
	if(!onoff)
	{
		gpio_pin_write(charger_gpio_dev,BOARD_BT_BOOST_EN_PIN,0);
	}
	else
	{	
		gpio_pin_write(charger_gpio_dev,BOARD_BT_BOOST_EN_PIN,1);
	}
}
void key_mute_ctl(u8_t onoff)
{
	if (!charger_gpio_dev)
	{
		return;
	}
	if(!onoff)
	{
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,0);
	}
	else
	{	
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
	}
}

void extmic_led_ctl(u8_t onoff)
{
	if (!charger_gpio_dev)
	{
		return;
	}
	if(onoff)
	{
		SYS_LOG_INF("exmic mute\n");
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_LED_CTL_PIN,0);
	}
	else
	{	
		SYS_LOG_INF("exmic unmute\n");
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_LED_CTL_PIN,1);
	}
}
#if 0
u8_t io_change_cnt=0;
u8_t io_status_cnt=0;
u8_t io_high_cnt=0;


//static void link_mute_io_timer(struct k_timer *timer)
static	void link_mute_io_timer(struct thread_timer *ttimer, void *expiry_fn_arg)
{
	if ((hotplug_manager_get_state(HOTPLUG_LINEIN) != HOTPLUG_IN)||(send_sync_msg==0))
	{
		if(thread_timer_is_running(&io_ctl_timer))
		{
			thread_timer_stop(&io_ctl_timer);
		}
		send_sync_msg=0;
		return;
	}
	send_sync_msg=1;
	set_tx_msg_by_pwm();
	k_sleep(1);
	sync_io_switch_to_pwm();
	#if 0
	if(send_sync_msg==0)
	{
		return;
	}
	if(send_sync_msg>2)
	{
		if(thread_timer_is_running(&io_ctl_timer))
		{
			thread_timer_stop(&io_ctl_timer);
		}
		gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN,
    	GPIO_DIR_IN | GPIO_INT |
   		GPIO_INT_EDGE | GPIO_INT_ACTIVE_LOW);
		gpio_pin_enable_callback(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN);
		if(send_sync_msg==5)
		{
			send_sync_msg=0;
			return;
		}
		thread_timer_init(&io_ctl_timer, link_mute_io_timer, NULL);
		thread_timer_start(&io_ctl_timer, 600, 600);
		send_sync_msg-=2;
		return;
	}
	if(send_sync_msg==1)
	{
		link_mute_io_ctl(1,0,1);
	}
	else
	{
		link_mute_io_ctl(0,0,1);
	}
	#endif
}
void link_mute_sync_stop_check(u8_t mute_sync_flag)
{
	send_sync_msg=0;
	if(thread_timer_is_running(&io_ctl_timer))
	{
		thread_timer_stop(&io_ctl_timer);
	}
	SYS_LOG_INF("stop send msg!\n");
}
void link_mute_sync_start_check(void)
{
	k_sleep(1);
	switch_io_func_to_uart_rx();
	send_sync_msg=1;
	thread_timer_init(&io_ctl_timer, link_mute_io_timer, NULL);
	thread_timer_start(&io_ctl_timer, 2000, 2000);
}
#endif
void link_mute_pin_int_enable(u8_t onoff)
{
	gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN,
    	GPIO_DIR_IN | GPIO_INT |
   		GPIO_INT_EDGE | GPIO_INT_ACTIVE_LOW);
	if(onoff)
	{
		gpio_pin_enable_callback(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN);
	}
	else
	{
		gpio_pin_disable_callback(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN);
	}
	
}


void link_mute_io_ctl(u8_t mode,u8_t onoff,u8_t rx_flag)
{
	#if 0
	if (!charger_gpio_dev)
	{
		return;
	}
	
	if(thread_timer_is_running(&io_ctl_timer))
	{
		thread_timer_stop(&io_ctl_timer);
	}
	send_sync_msg=1;
	#if 1
	SYS_LOG_INF("set mode:%d\n",mode);
	if(mode==0)
	{
		set_tx_msg_by_pwm();
	}
	else
	{
		set_tx_msg_by_pwm();
	}
	k_sleep(1);
	sync_io_switch_to_pwm();
	thread_timer_init(&io_ctl_timer, link_mute_io_timer, NULL);
	thread_timer_start(&io_ctl_timer, 2000, 2000);
	#else
	//set_tx_msg_by_pwm();
	//return;
	if(mode==0)//sent unmute msg
	{		
		SYS_LOG_INF("send unmute msg!\n");
		gpio_pin_disable_callback(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN);
		gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN, GPIO_DIR_OUT);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,0);
		k_sleep(1);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
		k_sleep(1);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,0);
		k_sleep(1);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
		k_sleep(1);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,0);
		k_sleep(1);		
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
		#if 0
		k_sleep(1);		
		gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN,
    	GPIO_DIR_IN | GPIO_INT |
   		GPIO_INT_EDGE | GPIO_INT_ACTIVE_LOW);
		gpio_pin_enable_callback(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN);
		#endif
		send_sync_msg=4;
	}
	else //send mute msg
	{
		SYS_LOG_INF("send mute msg!\n");
		gpio_pin_disable_callback(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN);
		gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN, GPIO_DIR_OUT);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,0);
		k_sleep(1);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
		k_sleep(1);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,0);
		k_sleep(1);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
		k_sleep(1);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,0);
		k_sleep(1);		
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
		k_sleep(1);
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,0);
		k_sleep(1);		
		gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,1);
		#if 0
		k_sleep(1);
		gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN,
    	GPIO_DIR_IN | GPIO_INT |
   		GPIO_INT_EDGE | GPIO_INT_ACTIVE_LOW);
		gpio_pin_enable_callback(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN);
		#endif
		send_sync_msg=3;
		
	}
	if(rx_flag==2)
	{
		send_sync_msg=5;
	}
	if(send_sync_msg!=0)
	{
		thread_timer_init(&io_ctl_timer, link_mute_io_timer, NULL);
		if(send_sync_msg==5)
		{
			thread_timer_start(&io_ctl_timer, 200, 100);
		}
		else
		{
			thread_timer_start(&io_ctl_timer, 40, 100);
		}
	}
	#endif
	//send_tx_msg();
	#endif
}

void charger_speech_ctl(u8_t mode)
{
	if (!charger_gpio_dev)
	{
		return;
	}
	if(mode)
	{
		
		gpio_pin_write(charger_gpio_dev,BOARD_CHARGER_TYPE_CTL_PIN,0);
	}
	else
	{	
		SYS_LOG_INF("charge slow mode\n");
		gpio_pin_write(charger_gpio_dev,BOARD_CHARGER_TYPE_CTL_PIN,1);
	}
}
void charger_type_ctl_init(void)
{
	charger_gpio_dev=device_get_binding(CONFIG_GPIO_ACTS_DEV_NAME);
	if (!charger_gpio_dev) {
		SYS_LOG_INF("cannot found gpio_dev %s\n", CONFIG_GPIO_ACTS_DEV_NAME);
		return;
	}
	gpio_pin_configure(charger_gpio_dev, BOARD_CHARGER_TYPE_CTL_PIN,
			   GPIO_DIR_OUT);
	gpio_pin_write(charger_gpio_dev,BOARD_CHARGER_TYPE_CTL_PIN,0);
	gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_LED_CTL_PIN,
			   GPIO_DIR_OUT);
	gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_LED_CTL_PIN,1);

	//gpio_pin_configure(charger_gpio_dev, BOARD_EXMIC_MUTE_CTL_PIN,
	//		   GPIO_DIR_OUT);
	//gpio_pin_write(charger_gpio_dev,BOARD_EXMIC_MUTE_CTL_PIN,0);
	
	gpio_pin_configure(charger_gpio_dev, BOARD_BT_BOOST_EN_PIN,
			   GPIO_DIR_OUT);
	gpio_pin_write(charger_gpio_dev,BOARD_BT_BOOST_EN_PIN,1);

	gpio_pin_configure(charger_gpio_dev, BOARD_PLAY_CTL_PIN,
			   GPIO_DIR_OUT);
	gpio_pin_write(charger_gpio_dev,BOARD_PLAY_CTL_PIN,0);
	gpio_pin_configure(charger_gpio_dev, BOARD_LINK_CTL_PIN,
			   GPIO_DIR_OUT);
	gpio_pin_write(charger_gpio_dev,BOARD_LINK_CTL_PIN,0);
	//link_mute_io_ctl(0,0,1);
	send_sync_msg=0;
	//thread_timer_init(&io_ctl_timer, link_mute_io_timer, NULL);
	//thread_timer_start(&io_ctl_timer, 1000, 1000);

}
u8_t power_get_low_power_status(void)
{
	return power_manager->low_power_flag;
}
void power_supply_report(bat_charge_event_t event, bat_charge_event_para_t *para)
{
	if (!power_manager) {
		return;
	}
	SYS_LOG_INF("event %d\n", event);
	switch (event) {
	case BAT_CHG_EVENT_DC5V_IN:
		break;
	case BAT_CHG_EVENT_DC5V_OUT:
		break;
	case BAT_CHG_EVENT_CHARGE_START:
		break;
	case BAT_CHG_EVENT_CHARGE_FULL:
		power_manager->charge_full_flag = 1;
		set_bat_status(1);
		break;

	case BAT_CHG_EVENT_VOLTAGE_CHANGE:
		SYS_LOG_INF("voltage change %u uV\n", para->voltage_val);
		power_manager->current_vol = para->voltage_val;
		set_bat_status(0);
		break;

	case BAT_CHG_EVENT_CAP_CHANGE:
		SYS_LOG_INF("cap change %u\n", para->cap);
		power_manager->current_cap = para->cap;
		power_manager->battary_changed = 1;
		set_bat_status(0);
		break;

	default:
		break;
	}
}

static int get_system_bat_info(int property)
{
	union power_supply_propval val;

	int ret;

	if (!power_manager || !power_manager->dev) {
		SYS_LOG_ERR("dev not found\n");
		return -ENODEV;
	}

	ret = power_supply_get_property(power_manager->dev, property, &val);
	if (ret < 0) {
		SYS_LOG_ERR("get property err %d\n", ret);
		return -ENODEV;
	}

	return val.intval;
}

int power_manager_get_battery_capacity(void)
{
#ifdef CONFIG_TWS
	int report_cap = get_system_bat_info(POWER_SUPPLY_PROP_CAPACITY);
	if (bt_manager_tws_get_dev_role() == BTSRV_TWS_MASTER) {
		if (report_cap > power_manager->slave_cap)
			report_cap = power_manager->slave_cap;
	}
	return report_cap;
#else
	return get_system_bat_info(POWER_SUPPLY_PROP_CAPACITY);
#endif
}

int power_manager_get_charge_status(void)
{
	return get_system_bat_info(POWER_SUPPLY_PROP_STATUS);
}

int power_manager_get_battery_vol(void)
{
	return get_system_bat_info(POWER_SUPPLY_PROP_VOLTAGE_NOW);
}

int power_manager_get_dc5v_status(void)
{
	return get_system_bat_info(POWER_SUPPLY_PROP_DC5V);
}

int power_manager_set_slave_battery_state(int capacity, int vol)
{
	power_manager->slave_vol = vol;
	power_manager->slave_cap = capacity;
	power_manager->battary_changed = 1;
	SYS_LOG_INF("vol %dmv cap %d\n", vol, capacity);
	return 0;
}

bool power_manager_check_is_no_power(void)
{
	if (power_manager_get_dc5v_status())
		return false;

	if (power_manager_get_battery_vol() <= power_manager->nopower_level) {
		SYS_LOG_INF("%d %d too low", power_manager_get_battery_vol(), power_manager_get_battery_capacity());
		return true;
	}

	return false;
}


int power_manager_sync_slave_battery_state(void)
{
	u32_t send_value;

#ifdef CONFIG_BT_TWS_US281B
	send_value = power_manager->current_cap / 10;
#else
	send_value = (power_manager->current_cap << 24) | power_manager->current_vol;
#endif

	bt_manager_tws_send_event(TWS_BATTERY_EVENT, send_value);
	return 0;
}

static int _power_manager_work_handle(void)
{
	if (!power_manager)
		return -ESRCH;

	if (power_manager->battary_changed) {
		power_manager->battary_changed = 0;
	#ifdef CONFIG_TWS
		if (bt_manager_tws_get_dev_role() == BTSRV_TWS_SLAVE) {
			power_manager_sync_slave_battery_state();
		} else if (bt_manager_tws_get_dev_role() == BTSRV_TWS_MASTER) {
			int report_cap = power_manager->current_cap;

			if (report_cap > power_manager->slave_cap)
				report_cap = power_manager->slave_cap;

			bt_manager_hfp_battery_report(BT_BATTERY_REPORT_VAL, report_cap);
		} else {
			bt_manager_hfp_battery_report(BT_BATTERY_REPORT_VAL, power_manager->current_cap);
		}
	#else
		bt_manager_hfp_battery_report(BT_BATTERY_REPORT_VAL, power_manager->current_cap);
	#endif
	}
	if (power_manager->charge_full_flag) {
		power_manager->charge_full_flag = 0;
		sys_event_send_message(MSG_FULL_POWER);
		//sys_event_notify(SYS_EVENT_CHARGE_FULL);
	}
	if (power_manager_get_dc5v_status())
	{
		if(power_manager->low_power_flag==1)
		{
			power_manager->low_power_flag=0;
			power_manager->report_timestamp=0;
			//sys_event_send_message(MSG_POWER_NORMAL);
		}
		return 0;
	}
		

	
	#if 1
	if (power_manager->current_vol <= power_manager->nopower_level) {
		SYS_LOG_INF("%d %d too low\n", power_manager->current_vol, power_manager->nopower_level);
		sys_event_notify(SYS_EVENT_BATTERY_TOO_LOW);
		return 0;
	}
	#endif
	//SYS_LOG_INF("cur bat:%d \n", power_manager->current_vol);
	if ((power_manager->current_vol <= power_manager->lowpower_level)
		&& ((os_uptime_get_32() - power_manager->report_timestamp) >=  DEFAULT_REPORT_PERIODS
			|| !power_manager->report_timestamp)) {
		SYS_LOG_INF("%d %d low\n", power_manager->current_vol, power_manager->slave_vol);						
	#ifdef CONFIG_TWS
		if (bt_manager_tws_get_dev_role() != BTSRV_TWS_SLAVE) {
			sys_event_notify(SYS_EVENT_BATTERY_LOW);
		}
	#else
		sys_event_notify(SYS_EVENT_BATTERY_LOW);
	#endif
		power_manager->report_timestamp = os_uptime_get_32();
	}
	else if(power_manager->current_vol<=DEFAULT_LOWERPOWER_LEVEL)
	{
		if(power_manager->low_power_flag==0)
		{
			power_manager->low_power_flag=1;
			sys_event_send_message(MSG_LOW_POWER);
		}
	}
	else if(power_manager->current_vol > power_manager->lowpower_level)
	{
		if(power_manager->low_power_flag==1)
		{
			power_manager->low_power_flag=0;
			power_manager->report_timestamp=0;
			//sys_event_send_message(MSG_POWER_NORMAL);
		}
		
	}
	return 0;
}

static struct power_manager_info global_power_manager;

int power_manager_init(void)
{
	power_manager = &global_power_manager;

	memset(power_manager, 0, sizeof(struct power_manager_info));

	power_manager->dev = device_get_binding("battery");
	if (!power_manager->dev) {
		SYS_LOG_ERR("dev not found\n");
		return -ENODEV;
	}

	if ((power_manager_get_battery_vol() <= DEFAULT_BOOTPOWER_LEVEL)
			&& (!power_manager_get_dc5v_status())) {
		SYS_LOG_INF("no power ,shundown: %d\n", power_manager_get_battery_vol());
		sys_pm_poweroff();
		return 0;
	}


	power_supply_register_notify(power_manager->dev, power_supply_report);
#ifdef CONFIG_PROPERTY
	power_manager->lowpower_level =property_get_int(CFG_LOW_POWER_WARNING_LEVEL, DEFAULT_LOWPOWER_LEVEL);  
	power_manager->nopower_level =property_get_int(CFG_SHUTDOWN_POWER_LEVEL,DEFAULT_NOPOWER_LEVEL);
#else
	power_manager->lowpower_level = DEFAULT_LOWPOWER_LEVEL;
	power_manager->nopower_level = DEFAULT_NOPOWER_LEVEL;
#endif
	power_manager->current_vol = power_manager_get_battery_vol();
	power_manager->current_cap = power_manager_get_battery_capacity();
	power_manager->slave_vol = 4200000;
	power_manager->slave_cap = 100;
	power_manager->report_timestamp = 0;

	sys_monitor_add_work(_power_manager_work_handle);
	charger_type_ctl_init();
	set_bat_status(0);

	return 0;
}
